<?php
/**
 * Mechanism
 * 
 * LICENSE
 * 
 * This file is private intellectual property of the author. 
 * All rights reserved. Copying and illegal using is punishable by law.
 * 
 * @copyright Copyright (c) 2011 BreatheInMyVoid ( BreatheInMyVoid@gmail.com )
 */

namespace Mechanism\Router\Route {
	/**
	 * 
	 * TODO: trim
	 * 		 url_decode
	 * 		 last slash in requested url 
	 * 			@see math( )
	 *
	 * @author BreatheInMyVoid ( BreatheInMyVoid@gmail.com )
	 */
	class Stationary extends Route {
		/**
		 * Path pattern
		 * 
		 * @var string 
		 */
		protected $route = null;
		
		/**
		 * 
		 * Build regex by route
		 *
		 * TODO: Reconsider regex building
		 * 
		 * @param string
		 */
		protected function assemble( $uri ) {
			$pattern = null;
			
			if ( !$uri) {
				throw new Exception( 'Route invalid or not setted' );
			}
			
			/* Get path for regex TODO: preg_quote() */		
			$pattern = str_replace( '/', '\/', $uri );
			
			if ( $this->is_vars_enabled) {
				$pattern = '/^' . $pattern . '[' . $this->vars_regex . '\/]*' . '$/';
			} else {
				$pattern = '/^' . $pattern . '*$/';
			}
						
			return $pattern;			
		}
		
		/**
		 * Disassemble url
		 * 
		 * If variables is enabled we store it in local array
		 * 
		 * TODO: Filter empty vars when store it in GET
		 * 		 Exception if /var/val/var/...
		 * 
		 * @param string
		 * @return void
		 */
		protected function disassemble( $uri ) {
			if ( $this->is_vars_enabled ) {
				/* -1 - delete last slash */	
				$vars_str = ( '/' === substr( $uri , -1, 1 ) ) ?
								 substr( $uri , strlen( $this->route ), -1 ) :
								 substr( $uri , strlen( $this->route ) );

				if ( !$vars_str ) {
					return;
				}			 	
							
				$vars_arr = explode( '/', $vars_str );
				$vars_arr_len = count( $vars_arr );
				
				/* Store finded variables */
				for ( $i = 0; $i < $vars_arr_len; $i += 2 ) {
					$key = $vars_arr[ $i ];
					
					/* Pass unnamed variables */
					if ( !$key ) {
						continue;
					}

					$value = isset( $vars_arr[ $i + 1 ] ) ? 
						$vars_arr[ $i + 1 ] : null;

					$this->vars[ $key ] = $value;
				}
			} else {
				/* Nothing to disassemble */
				return;
			}
		}
		
		/**
		 * Constructor
		 * 
		 * Expects staric route rule without
		 * slashes on start and end of it. Because
		 * it creates couple of problems. If it had *
		 * on the end it means variables enabled.
		 * 
		 * Example:
		 *     'articles/2009' or 'articles/2009/*'
		 * 
		 * @param string
		 */
		public function __construct( $route ) {
			if ( '*' === substr( $route, -1, 1 ) ) {
				$this->is_vars_enabled = true;
				$this->route = '/' . substr( $route, 0, -1 );
			} else { 	
				$this->route = '/' . $route;
			}			
		}

		/**
		 * 
		 */
		public function set_rule( $part, $rule ) {
			if ( '*' === $part ) {
				$this->vars_regex = $rule;	
				return $this;
			} else {
				return $this;
			}
		}
		
		/**
		 * TODO: Refactor preg_match 
		 *		 Exception
		 *
		 * @param string
		 */
		public function match( $uri ) {
			/* Normalaize */
			if ( '/' !== substr( $uri , -1, 1 ) ) {
				 $uri =  $uri . '/';
			}
			
			$pattern = $this->assemble( $this->route );
			
			if ( preg_match( $pattern, $uri ) ) {
				$this->disassemble( $uri );
				return true;
			} else {
				return false;
			}
		}
	}
} 
